package customgeneric;

/**
 * @author DCSGO
 * @version 1.0
 * 自定义泛型方法
 */
public class CustomMethodGeneric {
    //基本语法
    //修饰符 <T,R..>返回类型 方法名(参数列表){
    // }
    //注意细节
    //1.泛型方法 可以定义在普通类中 也可以定义在泛型类中
    //2.当泛型方法被调用时 类型参数被确定
    //3.public void eat(E e) {},修饰符后没有<T,R..> eat
    //  方法不是泛型方法 而是使用了泛型
    public static void main(String[] args) {
        new AA().m1("hi", 111);
        //AA.m1->t.getClass: class java.lang.String
        //AA.m1->r.getClass: class java.lang.Integer
        new BB<String, Integer>().m2(1.1F, false);
        //BB.m2->v.getClass: class java.lang.Float
        //BB.m2->r.getClass: class java.lang.Boolean
        //输出 Boolean 而不是 Integer 表明当泛型方法与它所在的
        //泛型类有相同的类型参数时 泛型方法使用的是它自身的类型参数
        //因此不推荐泛型方法与泛型类有相同的类型参数 避免出现不可预见的 Bug

        new BB<String, Integer>().m3(1.2, "1");
        //BB.m3->v.getClass: class java.lang.Double
        //BB.m3->t.getClass: class java.lang.String

        //new BB<String,Integer>().m3(1.2,11);//编译错误 int 与 String 不兼容
    }
}

class AA {
    public <T, R> void m1(T t, R r) {//泛型方法 定义在普通类中
        System.out.println("AA.m1->t.getClass: " + t.getClass());
        System.out.println("AA.m1->r.getClass: " + r.getClass());
    }
}

class BB<T, R> {
    public <V, R> V m2(V v, R r) {//泛型方法 定义在泛型类中
        System.out.println("BB.m2->v.getClass: " + v.getClass());
        System.out.println("BB.m2->r.getClass: " + r.getClass());
        return v;
    }

    public <V> void m3(V v, T t) {//泛型方法中使用泛型类的类型参数
        System.out.println("BB.m3->v.getClass: " + v.getClass());
        System.out.println("BB.m3->t.getClass: " + t.getClass());
    }
}
